package cn.denvie.agent.logger;

import cn.denvie.agent.common.AgentConfig;
import cn.denvie.agent.common.AgentException;
import cn.denvie.agent.utils.DateUtils;
import cn.denvie.agent.utils.StringUtils;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件日志。
 *
 * @author DengZhaoyong
 * @version 1.0.0
 */
public class FileLogger implements ILogger {

    private ThreadLocal<FileWriter> fileWriter = new ThreadLocal<>();

    private String rootDir = AgentConfig.DEFAULT_LOG_ROOT_DIR;
    private String dirPattern = AgentConfig.DEFAULT_LOG_PATH_PATTERN;
    private String fileName = AgentConfig.DEFAULT_LOG_FILE_NAME;

    public FileLogger() {
        // initFileWriter();
    }

    @Override
    public void info(Object content) {
        write(content == null ? "" : content.toString());
    }

    @Override
    public void error(Object content) {
        info(content);
    }

    public FileLogger setRootDir(String rootDir) {
        if (!StringUtils.isEmpty(rootDir)) {
            this.rootDir = rootDir;
        }
        return this;
    }

    public FileLogger setDirPattern(String dirPattern) {
        if (!StringUtils.isEmpty(dirPattern)) {
            this.dirPattern = dirPattern;
        }
        return this;
    }

    public FileLogger setFileName(String fileName) {
        if (!StringUtils.isEmpty(fileName)) {
            this.fileName = fileName;
        }
        return this;
    }

    private void write(String log) {
        try {
            final FileWriter write = getFileWriter();
            write.write(log + "\r\n");
            write.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private FileWriter getFileWriter() {
        if (fileWriter.get() == null) {
            try {
                fileWriter.set(new FileWriter(openFile(), true));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return fileWriter.get();
    }

    private File openFile() {
        try {
            String baseDir = System.getProperty("user.dir") + File.separator + rootDir;
            File root = new File(baseDir,
                    DateUtils.longToDateStr(System.currentTimeMillis(), dirPattern));
            if (!root.exists() || !root.isDirectory()) {
                root.mkdirs();
            }
            File file = new File(root, fileName);
            if (!file.exists()) {
                file.createNewFile();
            }
            return file;
        } catch (IOException e) {
            throw new AgentException(e);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // 模拟10000个线程同时写文件
        List<Thread> list = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            final int index = i;
            final FileLogger fileLogger = new FileLogger();
            list.add(new Thread() {
                @Override
                public void run() {
                    fileLogger.info("test agent " + index);
                }
            });
        }
        for (Thread thread : list) {
            thread.start();
        }
        for (Thread thread : list) {
            thread.join();
        }
    }
}
